(感動流淚中!沒想到完賽這天Day30
終於到來~~。寫IT文章原來可以是這麼興奮的事呢!)
Day30 請解釋Ruby的鴨子型別(Duck Type)? What is duck type?
如果你看到一隻鳥走起來像鴨子;游泳起來像鴨子;叫起來也像鴨子;那麼這隻鳥就可以被稱為鴨子。
參考發明Ruby的Yukihiro Matsumoto所寫的松本行弘談程式世界的未來(電子書)提到:如果只關心物件具備的方法,而不用考慮一個物件究竟是哪個類別的實體,就是鴨子型別。
Duck type
是一種用來譬喻動態型別語言(Dynamically Typed Language)
的設計風格。這種主要根據特徵
判斷的哲學,可以提供強大的靈活性,實現運行時的多型(polymorphism)
。
If it walks like a duck and quacks like a duck, it must be a duck.
大家應該都同意在這個世界上,資源有限,慾望無窮
,如何將電腦的資源(位元組)做有效的利用,是優秀程式設計師的重要課題。指定型別(指定ㄧ種資料型態給一組有用的位元資料),就是一種規劃資源的概念。
回首過去30天來,我們在鐵人賽第一天Day1的參賽宣言,在Ruby世界裡,幾乎萬物都為物件(Object)。產生物件的過程,需要將某個型別
(Type)實體化
(instantize)。
記得我們當初將實體化
的例子比喻為生小孩
的過程!而像Day11 Ruby 的 block, proc, lamdba方法比較
,其中lambda
就是由Proc
建立的實體。
寫了30天的Ruby經典面試題鐵人賽,用各種例子舉下來,我們都可以體會到Ruby就是一種靈活到不行的動態型別語言,Python
也是另一種很popular的動態型別語言。動態型別語言要在運行時,才對型別做判斷(是不是合法的)。
相較之下,靜態型別語言(Statically Typed Language)如c
, c++
, c##
, Java
,在使用變數之前就必須宣告資料型別,因此類型結構較為嚴謹,方法方便調用,但缺點是可讀性沒有動態語言清晰明瞭。靜態型別語言
在編譯(compile)
階段,就會先進行型別判斷,如果想達到多型的效果,就需要使用繼承
或介面(interface)
這種抽象型別(Abstract type)
。
超級比一比 | 靜態型別語言 | 動態型別語言 |
---|---|---|
程式語言 | c++ , bjective-C , Java ... |
Ruby , Python , Javascript ... |
何時宣告 | 在使用變數之前就必須宣告資料型別,讓變數具有資料儲存型別。 | 不需事先宣告變數的資料型別,就可以直接指定值 |
型別檢查(type check) | 在編譯(compile) 階段,就會先進行型別判斷 |
執行時判斷,一行行地將程式碼動態地直譯(interpret) 為機器碼執行,速度較慢。 |
多型(polymorphism) | 繼承 或介面(interface) 的抽象型別(Abstract type) |
動態。 |
まつもとゆきひろ(Matz先生)認為,型別資訊
與程式執行的本質
無關。而且在某些情況下,先設定好的型別也會造成制約。
(多了型別資訊的Java,不屬於演算法本身的程式碼占了行數更多呢!)
Ref: 松本行弘談程式世界的未來(電子書)
Ruby在意的不是物件的身份是什麼,而在於他能不能做什麼。
為了測試是不是鴨子:(是否滿足is-a關係
),我們可以使用鴨子測試(Duck Test)進行判斷。
來寫Ruby程式碼看看鐵人賽參賽者是不是都很會跑:
我們在Ruby程式碼宣告了Marathon Runner
,Ironman
兩個類別,Marathon Runner
和Ironman
都有run
方法(馬拉松選手
和鐵人三項
選手都要跑步!),但這兩個類別並非繼承關係。
class MarathonRunner
def initialize
end
def run #same method name
puts "I love long-distance running!"
end
end
class Ironman
def initialize
end
def run #same method name
puts "I love running!"
end
def swim
puts "I love swimming!"
end
def ride
puts "I love cycling!"
end
end
現在來建立第3個類別:Winner
,並且創造一個ITironman
方法,代入name
參數,恭喜任何完成第30天IT邦鐵人賽挑戰選手們的成就!
class Winner
def initialize
end
def ITironman name
name.run
end
end
ting = MarathonRunner.new
bater = Ironman.new
winner = Winner.new
winner.ITironman(ting)
winner.ITironman(bater)
Output:
vlan-2644-10-19-108-246:Ironman tingtinghsu$ ruby duck.rb
I love long-distance running!
I love running!
鐵人賽就像是一場對自己承諾想要進步更多
的長跑,恭喜完賽的鐵人們!
第30篇的面試經典題目選擇鴨子型別
還蠻有意義的!我們在學習一項新的技能(例如學習新的程式語言
),就像挑選用具、出門旅行一樣,必須選擇適合自己任務的工具,並知道自己為什麼做出這樣的選擇(Know your WHY
)。如果以解決問題的角度來說,選擇的工具是什麼材質做的,可能並不是最重要的。
整個10月份是我非常忙碌的月份(工作、完成國際講師課程認證、旅行、42K馬拉松完賽、潛水,參加英文演講比賽、去當其他英文演講比賽的評審),但我還是完成了IT鐵人賽!而且所寫的東西我以前完全不熟悉的Ruby
。(鐵人賽前5天時有一種:我常常看不懂自己在寫什麼
的感覺XDDD)
不過,再怎麼忙,每天都還是平均抽空3小時寫文章,而且為了應付忙碌的生活,我提前準備,事先計劃做的十分充足(甚至用spreadsheet和trello專案管理鐵人賽),總總投入心血,值得驕傲!
(我用trello card列出待解的Ruby面試題,並蒐集經典Ruby資料書籍)
(spreadsheet列出30天預計安排的大綱,做好寫作進度控管,不遺漏任何一天)
鐵人賽的完成並不是結束,而是個邁向更偉大航道的開始。
接下來我有三個計畫:
把鐵人賽文章修飾完成,改成英文版,放在我的個人blog。
所有Ruby程式碼整理後放到Github。
在IT邦寫一個新的系列Rails經典面試題目30題
在寫完這篇的三天後,我也要搬到有Matz先生的國度Japan
去,繼續讓Ruby on Rails豐富我下一段的旅程!
經過這30天內持續的努力,我的心態變得更強壯:)
我相信,只要是真心想完成一個目標,沒有任何事情是可以阻攔我的!
Ref:
期待大大的英文版
雖然,看不懂也不了解Ruby,但我也有跟到,這三十天來的神作之一!
每天都有看完啊...但就...
恭喜完賽
謝謝觀看我的作品~~哈哈哈!有跟讀者一起成長的感覺 ^^
太好了!恭喜完賽,經過這三十天的努力,ruby的基礎已經有很好的掌握了唷!
期待未來用Rails寫出自己的個人網站再串個金流$$$~~
恭喜大大完賽了!!
我也有在用trello
X,但沒有大大那麼豐富就是了D
謝謝神Q大大!今天就換你們完賽了呢 :D